﻿using HamcoWcs.Models.Charts;
using System;
using System.IO;
using System.Management;
using System.Threading.Tasks;

namespace HamcoWcs.Service.Common
{
    /// <summary>
    /// System.Management版本号5.0 其他版本会报错
    /// </summary>
    public class ComputerHelper
    {
        private const int KB_DIV = 1024;
        private const int MB_DIV = 1024 * 1024;
        private const int GB_DIV = 1024 * 1024 * 1024;

        /// <summary>获取磁盘使用情况详情</summary>
        public static string GetDriverUseDetail()
        {
            string result = "";
            foreach (DriveInfo drive in DriveInfo.GetDrives())
            {
                if (drive.DriveType == DriveType.Fixed)
                {
                    long total = drive.TotalSize / GB_DIV;
                    long free = drive.TotalFreeSpace / GB_DIV;
                    result += $"{drive.Name}:总空间={total}G 剩余空间{free}G\r\n";
                }
            }
            return result;
        }

        /// <summary>获取磁盘使用率</summary>
        public static UseRateDto GetDriverUsedRate()
        {
            try
            {
                long total = 0;
                long free = 0;
                foreach (DriveInfo drive in DriveInfo.GetDrives())
                {
                    if (drive.DriveType == DriveType.Fixed)
                    {
                        total += drive.TotalSize / GB_DIV;
                        free += drive.TotalFreeSpace / GB_DIV;
                    }
                }

                //var rate = Math.Abs(1 - (double)free / (double)total);
                return new UseRateDto("drive use info", total, free, "GB");
            }
            catch (Exception)
            {
                return null;
            }

        }


        /// <summary>获取可用内存 </summary>
        public static double GetMemoryAvailable()
        {

            long availablebytes = 0;
            var managementClassOs = new ManagementClass("Win32_OperatingSystem");
            foreach (var managementBaseObject in managementClassOs.GetInstances())
                if (managementBaseObject["FreePhysicalMemory"] != null)
                    availablebytes = 1024 * long.Parse(managementBaseObject["FreePhysicalMemory"].ToString());
            return (double)availablebytes / GB_DIV;

        }

        /// <summary>获取已用内存 </summary>
        public static double GetMemoryUsed()
        {
            double PhysicalMemory = GetPhysicalMemory();
            double MemoryAvailable = GetMemoryAvailable();
            double MemoryUsed = (double)(PhysicalMemory - MemoryAvailable);
            double currentMemoryUsed = (double)MemoryUsed;
            return currentMemoryUsed;
        }

        /// <summary>获取物理内存total </summary>
        public static double GetPhysicalMemory()
        {
            //获得物理内存
            var managementClass = new ManagementClass("Win32_ComputerSystem");
            var managementObjectCollection = managementClass.GetInstances();
            long PhysicalMemory;
            foreach (var managementBaseObject in managementObjectCollection)
                if (managementBaseObject["TotalPhysicalMemory"] != null)
                {
                    return long.Parse(managementBaseObject["TotalPhysicalMemory"].ToString()) / GB_DIV;
                }
            throw new Exception("");

        }

        /// <summary>获取内存使用率 </summary>
        public static UseRateDto GetMemoryUsedRate()
        {
            try
            {
                double PhysicalMemory = GetPhysicalMemory();
                double MemoryAvailable = GetMemoryAvailable();
                double? MemoryUsedRate = (double?)(PhysicalMemory - MemoryAvailable) / PhysicalMemory;
                return new UseRateDto("memory use info", PhysicalMemory, MemoryAvailable, "GB");
            }
            catch (Exception)
            {
                return null;
            }

        }

        /// <summary>获取内存使用率（异步方法）</summary>
        public static Task<UseRateDto> GetMemoryUsedRateAsync()
        => Task.Run(() => GetMemoryUsedRate());

        /// <summary>获取内存使用率（异步方法）</summary>
        public static Task<UseRateDto> GetDriverUsedRateAsync()
        => Task.Run(() => GetDriverUsedRate());
    }
}
